package com.ymx.darling.executor.mapping.metadata;

import com.ymx.darling.exception.ResultSetException;
import com.ymx.darling.type.TypeHandler;
import com.ymx.darling.type.TypeHandlerRegister;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.*;

/**
 * 结果集元数据处理器
 * @author 爱Java的小于
 */
public class MetaDataManager {

    /**
     * 为MetaData加入类型转换器
     * @param metaDataList 结果集的字段元数据
     */
    public static void addTypeHandler(List<MetaData> metaDataList) {
        metaDataList.forEach(metaData -> {
            if (Objects.isNull(metaData.getTypeHandler())) {
                //优先从MetaData中获取Field类型信息 如果Field为null则从JdbcType中获取相匹配的java类型
                Class<?> convertKey;
                if (Objects.nonNull(metaData.getField())) {
                    convertKey = metaData.getField().getType();
                } else {
                    convertKey = TypeHandlerRegister.getJavaType(metaData.getType());
                    if (Objects.isNull(convertKey)) {
                        throw new ResultSetException(String.format("darling不支持jdbc类型:'%s'", metaData.getType()));
                    }
                }
                // 获取类型转换器
                TypeHandler<?> typeHandler = TypeHandlerRegister.getTypeHandler(convertKey);
                metaData.setTypeHandler(typeHandler);
            }
        });
    }


    /**
     * 返回结果集元数据的实例列表
     * @param resultSet 结果集
     * @return List
     * @throws SQLException 可能会抛出此异常
     */
    public static List<MetaData> getMetaDataList(ResultSet resultSet) throws SQLException {
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();
        List<MetaData> metaDataList = new ArrayList<>(columnCount);
        //获取结果集中字段类型、字段名称 放入列表中
        for (int index = 1; index <= columnCount; index++) {
            metaDataList.add(new MetaData(
                    metaData.getColumnLabel(index),
                    metaData.getColumnType(index),
                    index
            ));
        }

        return metaDataList;
    }
}
